import React, {
  forwardRef,
  useCallback,
  useContext,
  useEffect,
  useImperativeHandle,
  useMemo,
  useState,
} from 'react';
import { ActionConfigType, ActionProps, TableModalProps } from '../../interfaces';
import '../../style.less';
import cls from 'classnames';
import { ActionEnum, EventsMap, ResConst } from '../../shared';
import { RenderForm } from '@inbiz/render';
import TableDrawer from './TableDrawer';
import Actions from './Actions';
import FullModal, { FullModalProps } from '../FullModal';
import { InBizTableCtx, InBizTableRefCtx } from '../../context';
import { useModalConfig } from '../../hooks';
import { getMessage } from '@inbiz/react';

const getPage = (page?: string) => {
  return page ? page.split(',') : [];
};
const TableModal = (props: TableModalProps, ref: any) => {
  const { state, tableCacheRef, primaryKey, relationField } = props;
  const { width, height, actions } = useModalConfig();
  const { emit, inbiz } = useContext(InBizTableCtx);
  const { eventsRef, pageRef } = useContext(InBizTableRefCtx);
  const [visible, setVisible] = useState(false);

  const [payload, setPayload] = useState<any>();
  const [extraParam, setExtraParam] = useState<any>();
  const { title, data, page, actionType, parentAction, openMode = 'modal' } = payload || {};

  useEffect(() => {
    if (visible) {
      (emit as any)?.(EventsMap.onOpen);
    }
  }, [visible]);

  useImperativeHandle(
    ref,
    () => {
      return {
        showModal: async (isShow: boolean, param?: any) => {
          if (isShow) {
            state.then((stateData: any) => {
              Promise.resolve(eventsRef?.current.onBeforeOpen?.(stateData)).then((res) => {
                setVisible(isShow);
                setExtraParam({...param, ...res});
              });
            })
            
          } else {
            setVisible(isShow);
            setExtraParam(param);
          }
        },
      };
    },
    [state],
  );
  useEffect(() => {
    if (state) {
      state
        .then((res: any) => {
          if (res && res !== ResConst.other) {
            setPayload(res);
          }
        })
        .catch((err: any) => {
          console.log('dispatch-err>>>', err);
        });
    }
  }, [state]);

  const filterActions = useMemo<ActionConfigType[] | undefined>(() => {
    if (!actions) {
      return;
    }

    const filtered = (actions as ActionProps[])
      .filter(
        (action) => action.parentAction === actionType || action.parentAction === parentAction,
      )
      .map((action) => {
        if (
          action.actionType &&
          [ActionEnum.save, ActionEnum.add, ActionEnum.saveAndNew].includes(
            action.actionType as ActionEnum,
          )
        ) {
          action.buttonType = 'primary';
        }
        return action;
      });
    return [...filtered];
  }, [actions, actionType, parentAction]);
  const [pageName, pageId] = getPage(page);
  // 触发页面初始化成功事件
  const handleInit = useCallback(() => {
    // 页面保存时触发
    pageRef?.current?.page.on('saveData', (_postData: any, res: any) => {
      if (data?.[primaryKey] || extraParam?.[primaryKey]) {
        emit?.('onEdit', res, _postData);
      } else {
        emit?.('onAdd', res, _postData);
      }
      // renderRef.current.onClose(res);
    });
  }, [pageId, data, extraParam]);

  const formatCacheData = (originData) => {
    const result = originData;
    const keys = Object.keys(result);
    keys.forEach((ele) => {
      if (keys.includes(`${ele}$raw`) && result[`${ele}$raw`]) {
        result[ele] = result[`${ele}$raw`];
      }
    });
    return result;
  };

  const renderForm = useCallback(() => {
    if (!pageId || !inbiz || !visible) {
      return null;
    }
    const _queryData = {
      ...data,
      ...extraParam,
      $primary: primaryKey,
      ...(tableCacheRef?.current.dataSetCache.getCacheData(data) ?? {}),
      $relationField: relationField,
      $relationFieldValue: data?.[relationField],
    };
    const isOrigin = Object.keys(_queryData?.masterDatas || {}).some(key => {
      if (!key.includes('@desc') && _queryData.masterDatas[key] !== undefined && _queryData.masterDatas[key] === _queryData[key + '@desc']) {
        return true
      } else {
        return false
      }
    })
    const queryData = tableCacheRef?.current.dataSetCache.tranformValue(_queryData);
    if (payload.actionType=== 'view' || payload.parentAction === 'view') {
      queryData._viewMode = 'look'
    }
    queryData['masterDatas'] = tableCacheRef?.current.dataSetCache.tranformValue(
      queryData['masterDatas'],
    );
    const cacheData = tableCacheRef?.current.dataSetCache.tranformValue(
      tableCacheRef?.current.dataSetCache.getCacheData(data),
      isOrigin
    );
    cacheData['masterDatas'] = tableCacheRef?.current.dataSetCache.tranformValue(
      cacheData['masterDatas'],
    );
    const anotherNameMap = tableCacheRef?.current?.anotherNameMap ?? {};
    Object.entries(anotherNameMap).forEach(([key, value]) => {
      if (key !== value) {
        if (queryData['masterDatas']) {
          queryData['masterDatas'][value] = queryData[key];
          if (cacheData?.masterDatas.hasOwnProperty(key)) {
            cacheData['masterDatas'][value] = cacheData[key];
          }
        }
        queryData[value] = queryData[key];
        if (cacheData.hasOwnProperty(key)) {
          cacheData[value] = cacheData[key];
        }
      }
    });
    return (
      <RenderForm
        ref={pageRef}
        key={`${pageId}_${data?.[primaryKey] || extraParam?.[primaryKey]}`}
        id={pageName}
        globalSDK={inbiz!.getGlobalSDK?.()}
        cacheData={formatCacheData(cacheData)}
        queryData={queryData}
        onInit={handleInit}
        type={'page'}
      />
    );
  }, [inbiz, pageId, data?.[primaryKey], payload, extraParam, visible]);

  const modalFooter = useMemo(
    () =>
      filterActions && (
        <Actions className={'modal-buttons'} actions={filterActions} displayQty={100} />
      ),
    [filterActions],
  );

  const onClose = () => {
    (emit as any)?.(EventsMap.onClick, props.actionType || 'cancel');
    Promise.resolve(eventsRef?.current.onBeforeClose?.() ?? true).then(() => {
      setVisible(false);
      (emit as any)?.(EventsMap.onClose);
      setPayload(undefined);
      setExtraParam(undefined);
    });
  };
  const modalProps: FullModalProps = {
    name: getMessage(title),
    centered: true,
    closable: false,
    visible,
    style: { height },
    width,
    className: cls('table-modal'),
    onClose,
    // onCancel: onClose,
    footer: modalFooter,
    render: renderForm,
    forceRender: true,
  };

  const drawerProps = {
    title: getMessage(title),
    visible,
    openMode,
    actions: filterActions,
    width,
    height,
    onClose,
    render: renderForm,
  };

  return 'modal' === openMode ? <FullModal {...modalProps} /> : <TableDrawer {...drawerProps} />;
};

export default React.memo(forwardRef(TableModal));
